home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / mac_at.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  13KB  |  571 lines

  1. /*
  2.  * This file contains the code for using the AppleTalk network.  This is a 
  3.  * first cut and hopefully it will work.
  4.  */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "timer.h"
  12. #include "ip.h"
  13. #include "arp.h"
  14. #include <MacTypes.h>
  15. #include <Appletalk.h>
  16. #include "mac_AT.h"
  17. #include "trace.h"
  18.  
  19. struct at at[AT_MAX];        /* Per-controller info */
  20.  
  21. char appletalk_bdcst = 0xff;
  22.  
  23. unsigned    nat = 0;
  24.     
  25. /* Initialize interface */
  26. at_init(interface,bufsize)
  27. struct interface *interface;
  28. unsigned bufsize;    /* Maximum size of receive queue in PACKETS */
  29. {
  30.     register struct at *atp;
  31.     int16 dev;
  32.     char *malloc();
  33.     int err;
  34.     ABRecPtr abrrdptr;
  35.     ABRecPtr abrwrptr;
  36.     int node, net;        /* vars to hold my node id and net id */
  37.     
  38. #ifdef DEBUG
  39.     printf("at_init called\n");
  40. #endif
  41.     dev = interface->dev;
  42.     if ( dev >= nat )
  43.     {
  44.         printf("problem with dev entry.  Number is  %d, max = %d\n", dev,nat);
  45.         return(-1);
  46.     }
  47.     atp = &at[dev];
  48.     atp->rcvmax = bufsize;
  49.     /*
  50.      * see if the device is available for use with AppleTalk
  51.      */
  52.     err = MPPOpen();
  53.     if ( err != noErr )
  54.     {
  55.         printf("AppleTalk is not available on device  error %d\n", err);
  56.         return(-1);
  57.     }
  58.  
  59.     /*
  60.      * See if we can put our protocol type in and have the default handler use it
  61.      */
  62.     err = LAPOpenProtocol(atp->ProtoType, NULL);
  63.     if ( err != noErr)
  64.     {
  65.         /*
  66.          * In case we bombed out last time, try and remove the protocol type and try again
  67.          */
  68.         if ( LAPCloseProtocol(atp->ProtoType) != 0 )
  69.         {
  70.  
  71.             printf("Could not initialize AppleTalk with protocol type %d, error %d\n",
  72.                  atp->ProtoType, err);
  73.             return(-1);
  74.         }
  75.         err = LAPOpenProtocol(atp->ProtoType, NULL);
  76.         if ( err != noErr)
  77.         {
  78.             printf("Could not initialize AppleTalk with protocol type %d, error %d\n",
  79.                  atp->ProtoType, err);
  80.             return(-1);
  81.         }
  82.     }
  83.     /*
  84.      * Since everything is alright, lets allocate an ABusRecord
  85.      */
  86.     
  87.     atp->rdATptr = NewHandle(lapSize);
  88.     if ( atp->rdATptr == NULL)
  89.     {
  90.         printf("Could not allocate handel for AppleBuss (0).\n");
  91.         (void)LAPCloseProtocol(atp->ProtoType);
  92.         return(-1);
  93.     }
  94.  
  95.     atp->wrATptr = NewHandle(lapSize);
  96.     
  97.     if ( atp->wrATptr == NULL)
  98.     {
  99.         printf("Could not allocate handel for AppleBuss (1).\n");
  100.         DisposHandle(atp->rdATptr);
  101.         (void)LAPCloseProtocol(atp->ProtoType);
  102.         return(-1);
  103.     }
  104.     
  105.     /*
  106.      * now that everything is going well, let's issue an async read on the protocol
  107.      */
  108.     HLock(atp->rdATptr);
  109.     HLock(atp->wrATptr);
  110.     abrrdptr = *atp->rdATptr;
  111.     abrwrptr = *atp->wrATptr;
  112.     
  113.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  114.     if ( at_startread(atp, abrrdptr) != 0 )
  115.     {
  116.         printf("Could not perform read on AppleTalk network.  Closing down device.\n");
  117.         return(-1);
  118.     }
  119.     
  120.     if ( GetNodeAddress( &node, &net) != 0)
  121.     {
  122.         printf("Could not get my own node address.  Something is wrong!!\n");
  123.         return(-1);
  124.     }
  125.     if ( interface->hwaddr == NULLCHAR )
  126.     {
  127.         if ( (interface -> hwaddr = malloc(4)) == NULLCHAR)
  128.         {
  129.             printf("Could not allocate memory for hardware address.\n");
  130.             return(-1);
  131.         }
  132.     }
  133.         
  134.     *interface->hwaddr = (unsigned char) node;
  135.     printf("My AppleTalk node number is %d\n", node);
  136.     return(0);
  137. }
  138.  
  139. /* Send an IP datagram on AppleTalk */
  140. at_send(bp,interface,gateway,precedence,delay,throughput,reliability)
  141. struct mbuf *bp;        /* Buffer to send */
  142. struct interface *interface;    /* Pointer to interface control block */
  143. int32 gateway;            /* IP address of next hop */
  144. char precedence;
  145. char delay;
  146. char throughput;
  147. char reliability;
  148. {
  149.     char *egate,*res_arp();
  150.     egate = res_arp(interface,ARP_APPLETALK,gateway,bp);
  151.     if(egate != NULLCHAR)
  152.     {
  153.         (*interface->output)(interface,egate,interface->hwaddr,AIP_TYPE,bp);
  154.     }
  155. }
  156.  
  157. /* Send a packet with Ethernet header */
  158. at_output(interface,dest,source,type,bp)
  159. struct interface *interface;        /* Pointer to interface control block */
  160. char dest[];        /* Destination Ethernet address */
  161. char source[];        /* Source Appletalk address */
  162. int16 type;        /* Type field */
  163. struct mbuf *bp;    /* Data field */
  164. {
  165.     struct    appletalk ap;    /* AppleTalk struct for header info. */
  166.     struct    mbuf    *hdr;
  167.     struct    mbuf    *htonat();
  168.  
  169.     memcpy(&ap.source, source, APPLE_LEN);
  170.     memcpy(&ap.dest, dest, APPLE_LEN);
  171.     ap.type = type;
  172.     hdr = htonat(&ap);
  173.     hdr->next = bp;
  174.     (*interface->raw)(interface,hdr);
  175. }
  176.  
  177. /* Send raw packet (caller provides header) */
  178. at_raw(interface,bp)
  179. struct interface *interface;        /* Pointer to interface control block */
  180. struct mbuf *bp;    /* Data field */
  181. {
  182.     register struct at *atp;    /* AppleTalk pointer */
  183.     short size;                    /* size of data in mbuf */
  184.     int err;                    /* error indicator from mac stuff */
  185.     short    tmp=2;                /* there is an offset of 2 in the data buffer */
  186.     short *mptr;                /* temporary pointer */
  187.     ABRecPtr abrwrptr;            /* pointer to applebuss record */
  188.     struct appletalk ap;        /* appletalk struct for front of record */
  189.     struct mbuf    *hdr;            /* extra mbuf pointer */
  190.     
  191.     atp = &at[interface->dev];
  192.     if ( interface->dev >= nat )
  193.     {
  194.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  195.         return(-1);
  196.     }
  197.     dump(interface,IF_TRACE_OUT,TRACE_APPLETALK,bp);
  198.     size = len_mbuf(bp);
  199.     
  200.     /*
  201.         Set up the transmit structure
  202.      */
  203.     
  204.     /*
  205.      * take a part to get the address
  206.      */
  207.     ntohat(&ap, &bp);
  208.     abrwrptr = *atp->wrATptr;
  209.     abrwrptr->lapProto.lapAddress.dstNodeID = ap.dest;
  210.     abrwrptr->lapProto.lapDataPtr = atp->buffer;
  211.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  212.     
  213.     /*
  214.      * now put header back on
  215.      */
  216.      
  217.     hdr = htonat(&ap);
  218.     hdr->next = bp;
  219.  
  220.     /*
  221.         Copy all the data from the mbuf to the data packet holder.
  222.         Max amount of data is 600 bytes
  223.      */
  224.     while  ( hdr != NULLBUF)
  225.     {
  226.         bcopy(hdr->data, &abrwrptr->lapProto.lapDataPtr[tmp], hdr->cnt);
  227.         tmp += hdr->cnt;
  228.         if ( tmp >= 600)
  229.             printf("sending: ERROR IN PACKET SIZE, size = %d\n", tmp);
  230.  
  231.         hdr = free_mbuf(hdr);
  232.     }
  233.  
  234.     /* 
  235.         set the packet length in the first two bytes of the LAP data buffer
  236.         including these two bytes.
  237.      */
  238.      
  239.     mptr = abrwrptr->lapProto.lapDataPtr;
  240.     *mptr = tmp;
  241.     
  242.     abrwrptr->lapProto.lapReqCount = tmp;
  243.     
  244.     atp->astats.out++;
  245.     
  246.     /* send off a sync write and wait for return value. */
  247.     
  248.     err = LAPWrite(atp->wrATptr, FALSE);
  249.     
  250.     if ( err != noErr )
  251.     {
  252.         printf("at_raw: write failure to AppleTalk (%d)\n", err);
  253.         return(0);
  254.     }
  255. }
  256.  
  257. /* Process any incoming AppleTalk packets on the receive queue */
  258. int
  259. at_recv(interface)
  260. struct interface *interface;
  261. {
  262.     struct at *atp;            /* appletalk pointer */
  263.     struct mbuf *bp;        /* place to store all the buffers */
  264.     ABRecPtr abrrdptr;        /* Appletalk network storage */
  265.     int    err;
  266.     extern int32 ip_addr;
  267.     struct appletalk ap;
  268.     struct mbuf *htonat();
  269.     
  270.     /*
  271.      *  just to make sure it is for us
  272.      */
  273.  
  274.     atp = &at[interface->dev];
  275.     
  276.     if ( interface->dev >= nat )
  277.     {
  278.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  279.         return(-1);
  280.     }
  281.     
  282.     /*
  283.      * get a pointer to the read structure
  284.      */
  285.     
  286.     abrrdptr = *atp->rdATptr;
  287.     
  288.     /*
  289.      * since this was an async read, a 1 indicates it has not completed yet.
  290.      */
  291.  
  292.     if ( abrrdptr->lapProto.abResult == 1)
  293.     {
  294.         return;
  295.     }
  296.     else if  ( abrrdptr->lapProto.abResult == buf2SmallErr)
  297.     {
  298.         atp->astats.badsize++;
  299.         if ( at_startread(atp, abrrdptr ) != 0)
  300.         {
  301.             printf("Error in starting async read on appletalk network.\n");
  302.         }
  303.         return(-1);
  304.     }
  305.     else if  ( abrrdptr->lapProto.abResult == readQErr)
  306.     {
  307.         atp->astats.drop++;
  308.         if ( at_startread(atp, abrrdptr ) != 0)
  309.         {
  310.             printf("Error in starting async read on appletalk network.\n");
  311.         }
  312.         return(-1);
  313.     }
  314.     
  315.     /*
  316.      * now set up the mbuf. count -2 because AT puts in the count sent in the first two]
  317.      * bytes of the data.
  318.      */
  319.     
  320.     if((bp = alloc_mbuf(abrrdptr->lapProto.lapActCount-2)) == NULLBUF)
  321.     {
  322.         atp->astats.nomem++;
  323.         if ( at_startread(atp, abrrdptr ) != 0)
  324.         {
  325.             printf("Error in starting async read on appletalk network.\n");
  326.         }
  327.         return(-1);
  328.     }
  329.     
  330.     /*
  331.      * move it over
  332.      */
  333.  
  334.     bcopy(&abrrdptr->lapProto.lapDataPtr[2], bp->data, abrrdptr->lapProto.lapActCount-2);
  335.     
  336.     bp->cnt = abrrdptr->lapProto.lapActCount - 2;
  337.     
  338.     /* not start another async read on this device. */
  339.         
  340.     if ( at_startread(at, abrrdptr) != 0 )
  341.     {
  342.         printf("Could not perform read on AppleTalk network.  Closing down device.\n");
  343.         return(-1);
  344.     }
  345.     ntohat(&ap, &bp);
  346.     
  347.     switch (ap.type)
  348.     {
  349.     
  350.         case AARP_TYPE:
  351.             arp_input(interface, bp);
  352.              atp->astats.any++;
  353.             break;
  354.         
  355.         case AIP_TYPE:
  356.             ip_route(bp, 0);
  357.              atp->astats.any++;
  358.             break;
  359.             
  360.         default:
  361.         /*
  362.             printf("at_recv: wrong type (%x)\n", ap.type);
  363.          */
  364.              atp->astats.badtype++;
  365.  
  366.              free_p(bp);
  367.             break;
  368.     }
  369. }
  370. /* Shut down the Ethernet controller */
  371. at_stop(interface)
  372. struct interface *interface;
  373. {
  374.     int16 dev;
  375.     struct at *atp;
  376.  
  377. #ifdef DEBUG
  378.     printf("at_stop called. dev = %d\n", interface->dev);
  379. #endif
  380.  
  381.     dev = interface->dev;
  382.     if ( dev >= nat)
  383.         return(-1);
  384.     atp = &at[dev];
  385.     
  386.     /* need to unlock the frozen pointers and cancel any reads outstanding */
  387.  
  388.     (void)HUnlock(atp->rdATptr);
  389.     (void)HUnlock(atp->wrATptr);
  390.     (void)LAPRdCancel(atp->rdATptr);
  391.  
  392.     /* make sure to close the procotol down and dispose or any pointers */
  393.     
  394.     (void)LAPCloseProtocol(atp->ProtoType);
  395.     (void)DisposHandle(atp->rdATptr);
  396.     (void)DisposHandle(atp->wrATptr);
  397.  
  398.     return(0);
  399. }
  400. /* Attach AppleTalk to the system
  401.  * argv[0]: hardware type, must be "0"
  402.  * argv[1]: Protocol Type, e.g., "77"
  403.  * argv[2]: device name,must be "B"
  404.  * argv[3]: mode, must be "arpa"
  405.  * argv[4]: interface label, e.g., "at0"
  406.  * argv[5]: maximum number of packets allowed on receive queue, e.g., "5"
  407.  * argv[6]: maximum transmission unit, bytes, e.g., "600" < appletalk limitation.
  408.  */
  409. at_attach(argc,argv)
  410. int argc;
  411. char *argv[];
  412. {
  413.     register struct interface *if_at;
  414.     extern struct interface *ifaces;
  415.     unsigned dev;
  416.     char *calloc(),*malloc();
  417.     int at_init();
  418.     int at_send();
  419.     int at_recv();
  420.     int at_stop();
  421.     int err;
  422.     int pat(),gat();
  423.  
  424.     if(nat >= AT_MAX){
  425.         printf("Too many AppleTalk controllers\r\n");
  426.         return -1;
  427.     }
  428.     dev = nat++;
  429.     if_at = (struct interface *)calloc(1,sizeof(struct interface));
  430.  
  431.     if_at->name = malloc((unsigned)strlen(argv[4])+1);
  432.     strcpy(if_at->name,argv[4]);
  433.     if_at->mtu = atoi(argv[6]);
  434.     if_at->send = at_send;
  435.     if_at->output = at_output;
  436.     if_at->raw = at_raw;
  437.     if_at->recv = at_recv;
  438.     if_at->stop = at_stop;
  439.     if_at->dev = dev;
  440.     if_at->flags = 0;
  441.     at[dev].ProtoType = htoi(argv[1]);
  442.     at[dev].net = malloc(strlen(argv[2])+1);
  443.     strcpy(at[dev].net, argv[2]);
  444.  
  445.     if(strcmp(argv[3],"arpa") != 0){
  446.         printf("Mode %s unknown for interface %s\r\n",
  447.             argv[3],argv[4]);
  448.         free((char *)if_at);
  449.         return -1;
  450.     }
  451.     arp_init(ARP_APPLETALK,APPLE_LEN,AIP_TYPE,AARP_TYPE,appletalk_bdcst,pat,gat);
  452.     if_at->next = ifaces;
  453.     ifaces = if_at;
  454.     /* Initialize device */
  455.     if ( (err = at_init(if_at,(unsigned)atoi(argv[5]))) != 0 )
  456.     {
  457.         printf("AT_INIT failed. err = %d\n", err);
  458.         return(-1);
  459.     }
  460.     else
  461.     {
  462.         return 0;
  463.     }
  464. }
  465.  
  466. /*
  467.     this procedure will start up an async read on the appletalk network
  468.  */
  469.  
  470. at_startread(atp, readptr)
  471. struct at *atp;
  472. ABRecPtr readptr;
  473. {
  474.     int err;
  475.     
  476.     /*
  477.      * set up the structure for a read
  478.      */
  479.      
  480.     readptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  481.     readptr->lapProto.lapReqCount = MAX_ATBUF;
  482.     readptr->lapProto.lapDataPtr = atp->buffer;
  483.  
  484.     err = LAPRead( atp->rdATptr, TRUE);
  485.     if ( err != noErr )
  486.     {
  487.         (void)LAPCloseProtocol(atp->ProtoType);
  488.         (void)DisposHandle(atp->rdATptr);
  489.         (void)DisposHandle(atp->wrATptr);
  490.         return(-1);
  491.     }            
  492.     return(0);
  493. }
  494.  
  495. bcopy(from, to, cnt)
  496. char *to, *from;
  497. int cnt;
  498. {
  499.     while ( cnt-- != 0 )
  500.     {
  501.         *to++ = *from++;
  502.     }
  503. }
  504. /* Format an AppleTalk address into a printable ascii string */
  505. pat(out,addr)
  506. char *out,*addr;
  507. {
  508.     sprintf(out,"%02x", *addr & 0xff);
  509. }
  510.  
  511. /* Convert an AppleTalk address from Hex/ASCII to binary */
  512. gat(out,cp)
  513. register char *out;
  514. register char *cp;
  515. {
  516.     register int i;
  517.  
  518.     *out = htoi(cp);
  519. }
  520.  
  521. /* Convert AppleTalk header in host form to network mbuf */
  522. struct mbuf *
  523. htonat(ap)
  524. struct appletalk *ap;
  525. {
  526.     struct mbuf *bp;
  527.     register char *cp;
  528.     bp = alloc_mbuf(APPLEADDRLEN);
  529.     bp->cnt = APPLEADDRLEN;
  530.     cp = bp->data;
  531.     memcpy(cp,&ap->dest,APPLE_LEN);
  532.     cp += APPLE_LEN;
  533.     memcpy(cp,&ap->source,APPLE_LEN);
  534.     cp += APPLE_LEN;
  535.     put16(cp,ap->type);
  536.  
  537.     return bp;
  538. }
  539. /* Extract AppleTalk header */
  540. ntohat(ap,bpp)
  541. struct appletalk *ap;
  542. struct mbuf **bpp;
  543. {
  544.     pullup(bpp,&ap->dest,APPLE_LEN);
  545.     pullup(bpp,&ap->source,APPLE_LEN);
  546.     ap->type = pull16(bpp);
  547.     return APPLEADDRLEN;
  548. }
  549.  
  550.  
  551.  
  552. int
  553. doatstat(argc,argv)
  554. int argc;
  555. char *argv[];
  556. {
  557.     struct at *atp;
  558.  
  559.     for(atp = at;atp < &at[nat]; atp++){
  560.         
  561.         printf("Controller %u:\n",atp-at);
  562.  
  563.         printf("any      output    badtype   nomem     drop     badsize\n");
  564.         printf("%-10lu%-10lu%-10lu%-10lu%-10lu%-10lu\n",
  565.          atp->astats.any, atp->astats.out,
  566.          atp->astats.badtype, atp->astats.nomem,
  567.          atp->astats.drop, atp->astats.badsize);
  568.     }
  569.     return 0;
  570. }
  571.